package com.alogic.blob.resource;

import com.alogic.blob.BlobReader;
import com.anysoft.util.*;
import org.apache.commons.lang3.StringUtils;
import org.w3c.dom.Element;

import java.io.File;
import java.io.InputStream;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.regex.Matcher;
import java.util.regex.Pattern;


/**
 * 数据文件(支持目录)
 *
 * @since 1.6.13.19 [20201014 duanyy]
 */
public class DataFile2 extends ResourceBlobManager {
    /**
     * 从路径中匹配id的正则表达式
     */
    protected static final Pattern idPattern0 = Pattern.compile("([^<>|:\"\"\\*\\?]+)\\.\\w+$");

    /**
     * 信息集
     */
    protected Map<String,ResourceBlobInfo> infos = new ConcurrentHashMap<String,ResourceBlobInfo>();

    /**
     * 文件后缀
     */
    protected String suffix=".json";

    public void configure(Properties p) {
        suffix = PropertiesConstants.getString(p,"suffix",suffix);
        super.configure(p);
    }

    @Override
    public BlobReader getFile(String id) {
        ResourceBlobInfo info = infos.get(id);
        return info == null ? null : new ResourceBlobReader(info,getBootstrap());
    }

    @Override
    public void report(Element xml) {
        if (xml != null){
            super.report(xml);
            XmlTools.setInt(xml, "count",infos.size());
        }
    }

    @Override
    public void report(Map<String, Object> json) {
        if (json != null){
            super.report(json);
            JsonTools.setInt(json, "count", infos.size());
        }
    }


    @Override
    public boolean existFile(String id) {
        return infos.containsKey(id);
    }

    @Override
    protected void resourceFound(String path) {
        InputStream in = null;
        try {
            in = bootstrap.getResourceAsStream(path);
            if (in != null){
                Matcher m = idPattern0.matcher(path);
                if (m.find()){
                    String id = m.group(1);
                    if (StringUtils.isNotEmpty(id)){
                        String shortId = id.substring(home.length());
                        if (StringUtils.isNotEmpty(shortId)) {
                            resourceFound(shortId, new ResourceBlobInfo(shortId, path, getContentType()));
                        }
                    }
                }
            }else{
                LOG.error("The resource is not valid :" + path);
            }
        }catch (Exception ex){
            LOG.error("Failed to build resource:" + id,ex);
        }finally{
            IOTools.close(in);
        }
    }

    @Override
    protected void scanJar(String home, JarFile pFile){
        Enumeration<JarEntry> files = pFile.entries();
        while (files.hasMoreElements()) {
            JarEntry entry = files.nextElement();
            String name = entry.getName();
            if (name.startsWith(home.substring(1)) && (name.endsWith(this.suffix))){
                resourceFound('/' + name);
            }
        }
    }

    @Override
    protected void scanFileSystem(String pHome, File pFile){
        File[] files = pFile.listFiles();
        for (File item:files){
            if (item.isDirectory()){
                scanFileSystem(pHome + "/" + item.getName(),item);
            }else {
                if (item.getName().endsWith(this.suffix)) {
                    resourceFound(pHome + "/" + item.getName());
                }
            }
        }
    }

    @Override
    protected void resourceFound(String id, ResourceBlobInfo info) {
        infos.put(id, info);
    }

    @Override
    public String list(List<String> ids, String cookies, int limit) {
        Iterator<String> keys = infos.keySet().iterator();

        while (keys.hasNext()){
            ids.add(keys.next());
        }

        return cookies;
    }
}